#ifndef AT_NETWORK_MQTT_CLIENT_h
#define AT_NETWORK_MQTT_CLIENT_h

#include "AtNetworkDevice.h"
#include "AtNetworkMqttTopic.h"

/**
 * MQTT 客户端表示长度定义
 */
#ifndef MQTT_CLIENTID_SIZE
#define MQTT_CLIENTID_SIZE 64
#endif

/**
 * MQTT 用户名长度定义
 */
#ifndef MQTT_USERNAME_SIZE
#define MQTT_USERNAME_SIZE 64
#endif

/**
 * MQTT 密码长度定义
 */
#ifndef MQTT_PASSWORD_SIZE
#define MQTT_PASSWORD_SIZE 64
#endif

/**
 * MQTT 服务器地址长度定义
 */
#ifndef MQTT_HOST_SIZE
#define MQTT_HOST_SIZE 128
#endif

class AtNetworkMqttClient {
  protected:
    AtNetworkDevice *device;

  public:
    GSM_STRING clientId; // MQTT client_id
    GSM_STRING username; // 服务器账号
    GSM_STRING password; // 服务器密码
    GSM_STRING host;     // 服务器地址
    uint16_t port;       // 服务器端口
    uint16_t cid;

  public:
    /**
     * 发布数据
     */
    virtual bool publish(const char *topic, char *body, size_t length) = 0;

    /**
     * 发布数据
     */
    inline bool publish0(const char *topic, char *body) {
      return this->publish(topic, body, strlen(body));
    };

    /**
     * 订阅主题
     */
    virtual bool subscribe(AtNetworkMqttTopic *topic, uint8_t qos) = 0;

    /**
     * 取消订阅主题
     */
    virtual bool unsubscribe(AtNetworkMqttTopic *topic) = 0;

    /**
     * 判定当前MQTT服务是否连接成功
     */
    virtual bool isConnected(uint32_t timeout = 1000) = 0;

    /**
     * 断开连接
     * @param timeout 超时时长
     */
    virtual bool diconnect(uint32_t timeout = 10000) = 0;

    /**
     * 初始化MQTT服务
     * @param timeout 超时时长
     */
    virtual bool connect(uint32_t timeout = 10000) = 0;

    /**
     * 设置MQTT客户端ID
     */
    inline void setClientId(const char *val) {
      strcpy(this->clientId, val);
    };

    /**
     * 设置MQTT鉴权用户
     */
    inline void setUsername(const char *val) {
      strcpy(this->username, val);
    };

    /**
     * 设置MQTT鉴权密码
     */
    inline void setPassword(const char *val) {
      strcpy(this->password, val);
    };

    /**
     * 设置MQTT-服务器地址
     */
    inline void setHost(const char *val) {
      strcpy(this->host, val);
    };

    /**
     * 设置MQTT-服务器端口
     */
    inline void setPort(uint16_t val) {
      this->port = val;
    };
};

#endif